package Matrixmultiply;

import java.math.BigDecimal;
import java.util.concurrent.CountDownLatch;

public class MatrixMultiply{
	private double[][] matrix1 = null;
	private double[][] matrix2 = null;
	private double[][] resultmatrix;
	private double[][] resultmatrix2;

	public MatrixMultiply(double[][] matrix1, double[][] matrix2) {
		this.matrix1 = matrix1;
		this.matrix2 = matrix2;
		resultmatrix = new double[matrix1.length][matrix2[1].length];
		resultmatrix2 = new double[matrix1.length][matrix2[1].length];
	}

	// 串行运算
	public double[][] Serialmultiply() {
		long startime = System.nanoTime();
		for (int i = 0; i < matrix1.length; i++) {
			for (int j = 0; j < matrix2[1].length; j++) {
				for (int k = 0; k < matrix2.length; k++) {
					resultmatrix[i][j] += matrix1[i][k] * matrix2[k][j];
				}
			}
		}
		long endtime = System.nanoTime();
		System.out.println("串行运算时间为：" + (endtime - startime) + "ns");
		return resultmatrix;
	}
	

	// 并行运算
	public double[][] Parallelmultiply(int threadnum) {
		int gap = matrix1.length / threadnum+1;
		Parallelthread []pt=new Parallelthread[threadnum];
		long endtime=0;
		long startime=System.nanoTime();
		for (int i = 0; i < threadnum; i++) {
			pt[i]=new Parallelthread(matrix1, matrix2,resultmatrix2, i, gap);
			pt[i].start();
		}
		for (int i=0;i<threadnum;i++) {
			try {
				pt[i].join();
				endtime = System.nanoTime();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		System.out.println("并行运算时间为：" + (endtime - startime) + "ns"+" 线程数："+threadnum);
		return resultmatrix;
	}

	public void printresult(double[][] matrix) {
		System.out.println("运算结果ResultMatrix"+"["+matrix1.length+"]"+"["+matrix2[1].length+"]"+"：");
		for (int i = 0; i < matrix.length; i++) {
			for (int j = 0; j < matrix[1].length; j++) {
				double number = matrix[i][j];
				BigDecimal decimal = new BigDecimal(number);
				double num = decimal.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
				System.out.print(num + "\t");
			}
			System.out.println();
		}
		System.out.println();
	}
	
	public boolean isright(double[][] matrix1, double[][] matrix2) {
		boolean isright=true;
		for(int i=0;i<matrix1.length;i++) {
			for(int j=0;j<matrix2[1].length;j++) {
				if(Math.abs(matrix1[i][j]-matrix1[i][j])>1*Math.pow(10, -9)) {
					isright=false;
					System.out.println("运算有误");
					return isright;
				}
			}
		}
		System.out.println("运算正确");
		return isright;
	}
	
	public static void main(String[] args) throws InterruptedException {
		// TODO Auto-generated method stub
		MatrixGenerator matrixGenerator=new MatrixGenerator();
		double [][]Matrix1=matrixGenerator.getMatrix1();
		double [][]Matrix2=matrixGenerator.getMatrix2();
		
		//同一矩阵不同线程数测试
		MatrixMultiply matrixMultiply=new MatrixMultiply(Matrix1, Matrix2);
		matrixMultiply.Serialmultiply();
		matrixMultiply.isright(matrixMultiply.resultmatrix, matrixMultiply.resultmatrix2);
        matrixMultiply.Parallelmultiply(5);
        
        MatrixMultiply matrixMultiply2=new MatrixMultiply(Matrix1, Matrix2);
        matrixMultiply2.Parallelmultiply(10);
        
        MatrixMultiply matrixMultiply3=new MatrixMultiply(Matrix1, Matrix2);
        matrixMultiply3.Parallelmultiply(20);

	}

}
